package cc.wubo.jpa;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import cc.wubo.jpa.entity.Book;
import cc.wubo.jpa.repository.BookRepository;
import cc.wubo.jpa.service.BookService;
/**
 *  一级缓存必须在事务范围之后才有效，这个缓存是必须存在的，不能关闭
 * 
 *  spring data jpa整合缓存的步骤
 *  1：选择使用哪个缓存框架（必须是jpa实现支持的）
 *  2：加入相关的依赖
 *  3：JpaProperty 里面配置使用二级缓存（不同的jpa实现，配置方法不同）
 *  
 *  注意：HibernateJpaVendorAdapter.getJpaPropertyMap()方法有bug
 *  
 *  JPA二级缓存模式
 *  SharedCacheMode.ALL所有的实体对象都缓存
 *  SharedCacheMode.NONE 不使用二级缓存
 *  SharedCacheMode.ENABLE_SELECTIVE 只要是实体对象上有Cacheable(true)的都缓存
 *  SharedCacheMode.DISABLE_SELECTIVE 只要是实体对象上有Cacheable(false)就不缓存，其他的实体都缓存
 *  SharedCacheMode.UNSPECIFIED 由JPA实现决定是否缓存
 *  
 *  二级缓存默认只对根据id查询有效（EntityManager.find，CrudRepository.findOne）
 *  如果是自定义的查询（不管是否是根据id查询）都不会用到二级缓存
 *  如果要自定义的查询使用二级缓存，则必须开启查询缓存，
 *  开启查询缓存必须和查询批注（@QueryHint(name="org.hibernate.cacheable",value="true")）一起使用
 *  否则，单独使用查询缓存是不会生效的
 *  
 *  CacheRetrieveMode.USE 默认值 ，从缓存读取数据
 *  CacheRetrieveMode.BYPASS 不从缓存读取数据，直接查询数据库
 */
@ComponentScan
@EnableJpaRepositories
@EnableTransactionManagement
public class App2 {
	
	private BookRepository br = null;
	private BookService bs= null;
	@Before
	public void init(){
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(App2.class);
		br = context.getBean(BookRepository.class);
		bs = context.getBean(BookService.class);
	}
	@Test
	public void run1(){
		Book book = new Book();
		book.setAuthor("aaa");
		book.setPrice(100.1);
		book.setTitle("aa");
		book.setType(1);
		br.save(book);
		
	}
	@Test
	public void testCacheⅡ(){
		System.out.println(br.findOne(1));
		System.out.println(br.findOne(1));
	}
	@Test
	public void testCacheⅠ(){
		bs.cache();
	}
	@Test
	public void queryCache(){
		br.findById(1);
		br.findById(1);
	}
	@Test
	public void getCacheObj(){
		br.findById(1);
		bs.jpaCache();
		br.findById(1);
	}
	
	

}
